/*
 * BotController.java
 *
 * Created on 16. Dezember 2006, 17:15
 *
 * Copyright (c) 2007 Daniel Gronau
 *
 * This file is part of KanjiTori.
 *
 * KanjiTori is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * KanjiTori is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
 *
 */

package kanjitori.graphics.bot;

import com.jme.animation.SpatialTransformer;
import com.jme.math.Vector3f;
import com.jme.scene.Controller;
import kanjitori.lesson.Entry;
import kanjitori.util.Randomizer;
import kanjitori.graphics.bot.Bot;
import kanjitori.map.Content;
import kanjitori.Player;
import kanjitori.events.BotKilledEvent;
import kanjitori.events.EntrySolvedEvent;
import kanjitori.events.ManagerService;
import kanjitori.events.PlayerHurtEvent;
import kanjitori.map.ContentMatrix;
import kanjitori.map.Position;

/**
 *
 * @author Pirx
 */
public class BotController extends Controller {
    
    //private final static Random RANDOM = new Random();
    private final static Position[] DIRS = new Position[]
    { Position.get(1, 0), Position.get(-1, 0), Position.get(0, 1), Position.get(0, -1)};
    
    
    private Position oldDir = DIRS[0];
    private ContentMatrix contentMatrix;
    
    private Position oldPos;
    private Position newPos;
    
    private Bot bot;
    
    private SpatialTransformer st;
    
    
    /** Creates a new instance of BotController 
     * @param bot 
     * @param contentMatrix 
     */
    public BotController(Bot bot, ContentMatrix contentMatrix) {
        this.contentMatrix = contentMatrix;
        this.bot = bot;
        
        newPos = contentMatrix.findFreePos();
        oldPos = newPos;
        contentMatrix.setContent(newPos, Content.BOT);
    }
    
    public void update(float time) {
        if (bot.checkPlayerCollision()) {
            collide();
        }
        if (st == null || st.getCurTime() == 1) {
            if (st == null) {
                bot.getNode().setLocalTranslation(new Vector3f(2 * oldPos.x(), 0, 2 * oldPos.y()));
                st = new SpatialTransformer(1);
                st.setObject(bot.getNode(), 0, -1);
                st.setRepeatType(Controller.RT_CLAMP);
                bot.getNode().addController(st);
            } else {
                contentMatrix.setContent(oldPos, Content.EMPTY);
            }
            Position newDirection = findFreeDirection(newPos, oldDir);
            if (newDirection == null) {
                return;
            }
            oldPos = newPos;
            newPos = newPos.add(newDirection);
            oldDir = newDirection;
            contentMatrix.setContent(newPos, Content.BOT);
            Vector3f newVector = new Vector3f(2 * newPos.x(), 0, 2 * newPos.y());
            st.setPosition(0, 0, bot.getNode().getLocalTranslation());
            st.setPosition(0, 1, newVector);
            st.setNewAnimationTimes(0, 1);
            st.setCurTime(0);
            st.interpolateMissing();
        }
    }
    
    public void collide() {
        Entry playerEntry = Player.getPlayer().getEntry();
        if (playerEntry == null || ! playerEntry.accept(bot.getValue())) {
            ManagerService.fireEvent(new PlayerHurtEvent(bot));
        } else {
            st.setActive(false);
            this.setActive(false);
            bot.die();
            ManagerService.fireEvent(new BotKilledEvent(bot));
            if (playerEntry.isSolved()) {
                ManagerService.fireEvent(new EntrySolvedEvent(playerEntry));
            }
        }
    }
       
    public Position findFreeDirection(Position pos, Position direction) {
        Randomizer<Position> rand = new Randomizer<Position>();
        for (int i = 0; i < 4; i++) {
            Position newPos = pos.add(DIRS[i]);
            if (! contentMatrix.isValidPos(newPos) 
                    || contentMatrix.getContent(newPos) != Content.EMPTY) {
                continue;
            }
            rand.add(DIRS[i], DIRS[i].equals(direction) ? 4 : 1);
        }
        return rand.size() == 0 ? null : rand.get();
    }

}


